package org.dcarew.javancss.util;

import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaModelException;

/**
 * A Visitor implementation for IJavaProjects, IPackageFragmentRoots, IPackageFragments, and
 * ICompilationUnits.
 * 
 * @author Devon Carew
 */
public abstract class JavaElementVisitor
{
	
	public static void accept(JavaElementVisitor visitor, IJavaElement javaElement)
		throws JavaModelException
	{
		if (javaElement instanceof IJavaProject)
			accept(visitor, (IJavaProject)javaElement);
		else if (javaElement instanceof IPackageFragmentRoot)
			accept(visitor, (IPackageFragmentRoot)javaElement);
		else if (javaElement instanceof IPackageFragment)
			accept(visitor, (IPackageFragment)javaElement);
		else if (javaElement instanceof ICompilationUnit)
			accept(visitor, (ICompilationUnit)javaElement);
		else
			throw new IllegalArgumentException("unhandled type: " + javaElement);
	}
	
	public static void accept(JavaElementVisitor visitor, IJavaProject javaProject)
		throws JavaModelException
	{
		if (!visitor.visit(javaProject))
			return;
		
		IPackageFragmentRoot[] roots = javaProject.getPackageFragmentRoots();
		
		for (int i = 0; i < roots.length; i++)
		{
			IPackageFragmentRoot packageFragmentRoot = roots[i];
			
			accept(visitor, packageFragmentRoot);
		}
	}
	
	
	public static void accept(JavaElementVisitor visitor, IPackageFragmentRoot packageFragmentRoot)
		throws JavaModelException
	{
		if (!visitor.visit(packageFragmentRoot))
			return;
		
		IJavaElement[] packageFragments = packageFragmentRoot.getChildren();
		
		for (int i = 0; i < packageFragments.length; i++)
		{
			IPackageFragment packageFragment = (IPackageFragment)packageFragments[i];
			
			accept(visitor, packageFragment);
		}
	}


	public static void accept(JavaElementVisitor visitor, IPackageFragment packageFragment)
		throws JavaModelException
	{
		if (!visitor.visit(packageFragment))
			return;
		
		ICompilationUnit[] compilationUnits = packageFragment.getCompilationUnits();
		
		for (int i = 0; i < compilationUnits.length; i++)
		{
			ICompilationUnit compilationUnit = compilationUnits[i];
			
			accept(visitor, compilationUnit);
		}
	}

	public static void accept(JavaElementVisitor visitor, ICompilationUnit compilationUnit)
		throws JavaModelException
	{
		visitor.visit(compilationUnit);
	}


	protected boolean visit(IJavaProject javaProject)
		throws JavaModelException
	{
		return true;
	}
	
	protected boolean visit(IPackageFragmentRoot packageFragmentRoot)
		throws JavaModelException
	{
		return true;
	}
	
	protected boolean visit(IPackageFragment packageFragment)
		throws JavaModelException
	{
		return true;
	}
	
	protected boolean visit(ICompilationUnit compilationUnit)
		throws JavaModelException
	{
		return true;
	}
	
}
